#include "Date.h"

void test1()
{
    Date d1(2024, 5, 18);
	Date d2(2024, 3, 20);
	Date d3(2024, 3, 20);

	cout << (d1 < d2) << endl;
	cout << (d1 > d2) << endl;
	cout << (d1 == d3) << endl;
	cout << (d2 <= d3) << endl;
	cout << (d2 == d3) << endl;
}

void test2()
{
    Date d1(2024, 11, 22);
    d1.Print();
    Date d2 = d1 + 10000;
    d2.Print();
}

void test3()
{
    Date d1(2024, 11, 23);
    d1.Print();
    Date d2 = d1 - 10000;
    d2.Print();
    cout << d2 - d1 << endl;
    cout << d1 - d2 << endl;
}

void test4()
{
    Date d1(2024, 11, 23);
    d1.Print();
    Date d2 = ++d1;
    d1.Print();
    d2.Print();
    Date d3 = d1++;
    d1.Print();
    d3.Print();
    Date d4 = --d1;
    d1.Print();
    d4.Print();
    Date d5 = d1--;
    d1.Print();
    d5.Print();
}

void test5()
{
    const Date d1(2024, 11, 28);
    Date d2 = d1 - 10; // const对象调用const成员函数
    // d1 -= 10; //const对象不可调用非const成员函数
    d2 -= 10; // 非const对象调用const成员函数
    Date d3 = d2 - 10; // 非const对象调用非const成员函数
    d1.Print();
    d2.Print();
    d3.Print();

    // const成员函数不能调用非const成员函数
    // void testConst() const
    // {
    //     Print();
    // }
}

void test6()
{
    Date d1, d2;
    cin >> d1 >> d2;
    cout << d1 << d2;
}

class A
{
public:
    explicit A(int a = 0)
    : m_a(a)
    {
        n++;
        m++;
        cout << "A(int)" << endl;
    }

    A(const A &a)
    : m_a(a.m_a)
    {
        cout << "A(const A&)" << endl;
    }

    ~A()
    {
        cout << "~A()" << endl;
        m--;
    }

    static void printStatic()
    {
        cout << n << " " << m << endl;
    }
private:
    int m_a;
    static int n; // 记录构造了多少个对象
    static int m; // 记录当前还有几个对象
};
int A::n = 0;
int A::m = 0;

int main()
{
    // A a = 1; // 支持单参数的隐式类型转换，正常先用1构造临时对象，然后拷贝构造，编译器进一步优化为直接构造，加了explicit后被禁止隐式类型转换
    A a(1); // 支持显示调用构造函数
    A b(1); // 有名对象，声明周期在当前作用域
    A::printStatic();
    A(); // 匿名对象，生命周期在这一行
    A::printStatic();
    // 匿名对象的作用
    A c(A(200)); // 使用200先构造一个匿名对象，然后拷贝构造给c，但是编译器对于连续的构造和拷贝构造会直接合并
    A::printStatic();
    return 0;
}